﻿using System;
using System.Linq;
using System.Threading.Tasks;
using Dapper;

namespace AspNet.Identity.Dapper
{
    public class RoleTable
    {
        private IdentityDbContextDapper _database;

        /// <summary>
        /// Constructor that takes a MySQLDatabase instance 
        /// </summary>
        /// <param name="database"></param>
        public RoleTable(IdentityDbContextDapper database)
        {
            _database = database;
        }

        /// <summary>
        /// Deltes a role from the Roles table
        /// </summary>
        /// <param name="roleId">The role Id</param>
        /// <returns></returns>
        public Task<int> Delete(string roleId)
        {
            string commandText = "Delete from Roles where Id = @id";
            return _database.Connection.ExecuteAsync(commandText, new { id = roleId });
        }

        /// <summary>
        /// Inserts a new Role in the Roles table
        /// </summary>
        /// <param name="roleName">The role's name</param>
        /// <returns></returns>
        public Task<int> Insert(IdentityRole role)
        {
            string commandText = "Insert into Roles (Id, Name) values (@id, @name)";
            return _database.Connection.ExecuteAsync(commandText, new
            {
                name = role.Name,
                id = role.Id
            });
        }

        /// <summary>
        /// Returns a role name given the roleId
        /// </summary>
        /// <param name="roleId">The role Id</param>
        /// <returns>Role name</returns>
        public Task<string> GetRoleName(string roleId)
        {
            string commandText = "Select Name from Roles where Id = @id";
            return _database.Connection.QueryFirstOrDefaultAsync<string>(commandText, new { id = roleId });
        }

        /// <summary>
        /// Returns the role Id given a role name
        /// </summary>
        /// <param name="roleName">Role's name</param>
        /// <returns>Role's Id</returns>
        public Task<string> GetRoleId(string roleName)
        {
            string commandText = "Select Id from Roles where Name = @name";

            return _database.Connection.QueryFirstOrDefaultAsync<string>(commandText, new { name = roleName });

        }

        /// <summary>
        /// Gets the IdentityRole given the role Id
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public IdentityRole GetRoleById(string roleId)
        {
            var roleName = GetRoleName(roleId).Result;
            IdentityRole role = null;

            if(roleName != null)
            {
                role = new IdentityRole(roleName, roleId);
            }

            return role;

        }

        /// <summary>
        /// Gets the IdentityRole given the role name
        /// </summary>
        /// <param name="roleName"></param>
        /// <returns></returns>
        public IdentityRole GetRoleByName(string roleName)
        {
            var roleId = GetRoleId(roleName).Result;
            IdentityRole role = null;

            if(roleId != null)
            {
                role = new IdentityRole(roleName, roleId);
            }

            return role;
        }

        public int Update(IdentityRole role)
        {
            string commandText = "Update Roles set Name = @name where Id = @id";

            return _database.Connection.ExecuteAsync(commandText, new
            {
                name = role.Name,
                id = role.Id
            }).Result;
        }
    }
}
